#include <ESP8266WiFi.h>

// Must use forked library
#include <ESPAsyncTCP.h>      // https://github.com/khoih-prog/ESPAsyncTCP

extern "C"
{
#include <osapi.h>
#include <os_type.h>
}

#include "config.h"

static os_timer_t intervalTimer;

static void replyToServer(void* arg) 
{
  AsyncClient* client = reinterpret_cast<AsyncClient*>(arg);

  // send reply
  if (client->space() > 32 && client->canSend()) 
  {
    char message[32];
    
    sprintf(message, "this is from %s", WiFi.localIP().toString().c_str());
    client->add(message, strlen(message));
    client->send();
  }
}

/* event callbacks */
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) 
{
  (void) arg;
  
  Serial.printf("\n data received from %s \n", client->remoteIP().toString().c_str());
  Serial.write((uint8_t*)data, len);

  os_timer_arm(&intervalTimer, 2000, true); // schedule for reply to server at next 2s
}

void onConnect(void* arg, AsyncClient* client) 
{
  (void) arg;
  
  Serial.printf("\n client has been connected to %s on port %d \n", SERVER_HOST_NAME, TCP_PORT);
  replyToServer(client);
}


void setup() 
{
  Serial.begin(115200);
  while (!Serial && millis() < 5000);
  
  delay(200);

  // connects to access point
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);
  
  while (WiFi.status() != WL_CONNECTED) 
  {
    Serial.print('.');
    delay(500);
  }

  AsyncClient* client = new AsyncClient;
  client->onData(&handleData, client);
  client->onConnect(&onConnect, client);
  client->connect(SERVER_HOST_NAME, TCP_PORT);

  os_timer_disarm(&intervalTimer);
  os_timer_setfn(&intervalTimer, &replyToServer, client);
}

void loop() 
{
}
